/*
 ============================================================================
 Name		: DaMaiModel.cpp
 Author	  : Gary
 Version	 : 1.0
 Copyright   : Your copyright notice
 Description : CDaMaiModel implementation
 ============================================================================
 */

#include <e32cmn.h>
#include <CHARCONV.H>
#include <UTF.H>
#include "DaMaiModel.h"
#include "sjson.h"
#include "e32hashtab.h"
using namespace sjson;


const TInt KDefaultBufferSize = 256;
_LIT8(KCityURL, "http://mapi.damai.cn/citylist.aspx");
_LIT8(KExhibitionHallURL, "http://mapi.damai.cn/VenList.aspx?id=");
_LIT8(KExhibitionHallItemURL, "http://mapi.damai.cn/ProjLst.aspx?v=");

//_LIT(KTestFormatedJson, "{\"project\":{\"name\":\"s60-json-library\"}, \"booleanVariable\":true, \"nullValue\":null, \"booleanVariable\":true, \"arrayOfValues\":[true,123,\"string\",1,null]}");
//_LIT(KTestFormatedJson1, "[{\"i\":852,\"s\":430,\"n\":\"\x5317\x4EAC\"},{\"i\":872,\"s\":307,\"n\":\"\x4E0A\x6D77\"}]");

CDaMaiModel::CDaMaiModel():iObserver(NULL)
	{
	// No implementation required
	}

CDaMaiModel::~CDaMaiModel()
	{
	delete iClient;
	iClient = NULL;
	
	//delete iObserver;
	//iObserver = NULL;
	}

CDaMaiModel* CDaMaiModel::NewLC()
	{
	CDaMaiModel* self = new (ELeave) CDaMaiModel();
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

CDaMaiModel* CDaMaiModel::NewL()
	{
	CDaMaiModel* self = CDaMaiModel::NewLC();
	CleanupStack::Pop(); // self;
	return self;
	}

void CDaMaiModel::ConstructL()
	{
		iClient = CDaMaiWebClientEngine::NewL(* this);
		//GetCitys();
		
		
//		_LIT8(kTestValue, "\u4e2d\\u6587\\u5185\\u5bb9\\u6d4b\\u8bd5");
//		HBufC8* val = DecodeJSONString(kTestValue);
//		HBufC8* val2 = EncodeJSONString(*val, EFalse);
	}


void CDaMaiModel::ClientEvent(const TDesC& aEventDescription)
	{
		//print....
	}


//当引擎接收到响应数据，调用该方法通知使用者
void CDaMaiModel::ClientBodyReceived(const TDesC8& aBodyData)
	{
	
	HBufC8* hBufC8Encode = EncodeJSONString1(aBodyData, EFalse);
//	CleanupStack::PushL(hBufC8Encode);
//	HBufC8* val31 = EncodeJSONString(aBodyData, EFalse);
//	HBufC8* val32 = DecodeJSONString(*val31);

//	HBufC16* buf16aBodyData = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aBodyData);
//	CleanupStack::PushL(buf16aBodyData);
//	TPtr16 ptr16(buf16aBodyData->Des());
//	//HBufC8* buf8aBodyData =CnvUtfConverter::ConvertFromUnicodeToUtf8L(*buf16aBodyData);
//	
//	
//	HBufC8* buf8 = HBufC8::NewL(ptr16.Length()*2);
//	 
//	TPtr8 ptr8( buf8->Des() );	
//	
//	CCnvCharacterSetConverter* conv = CCnvCharacterSetConverter::NewL();
//
//	CleanupStack::PushL(conv);
//
//	RFs fs;
//	User::LeaveIfError(fs.Connect());
//
//	if (conv->PrepareToConvertToOrFromL(KCharacterSetIdentifierAscii, fs) != CCnvCharacterSetConverter::EAvailable)
//	{
//	User::Leave(KErrNotSupported);
//	}

//	HBufC* str = HBufC::NewL(aBodyData.Length());
//	CleanupStack::PushL(str);
//
//	TPtr ptr = str->Des();
//	TInt state = CCnvCharacterSetConverter::KStateDefault;
//
//	if (conv->ConvertFromUnicode( ptr8,ptr16,state) == CCnvCharacterSetConverter::EErrorIllFormedInput)
//	{
//	User::Leave(KErrArgument);
//	}
//
//	fs.Close();
//	CleanupStack::PopAndDestroy(2);
	 
////		
//	TBuf16<5000> tbuf16;
//	tbuf16.Copy(*buf16aBodyData);
//	
//	TPtr16 t = buf16aBodyData->Des();
//	//buf16aBodyData->
//	TPtrC8 ptr8(reinterpret_cast<const TUint8*>(tbuf16.Ptr()),(tbuf16.Size()*2));
//	TBuf8<10000> tbuf8;
//	tbuf8 = ptr8;

//	CCnvCharacterSetConverter* conv = CCnvCharacterSetConverter::NewL();
//
//	CleanupStack::PushL(conv);
//
//	RFs fs;
//	User::LeaveIfError(fs.Connect());
//
//	if (conv->PrepareToConvertToOrFromL(KCharacterSetIdentifierAscii, fs) != CCnvCharacterSetConverter::EAvailable)
//	{
//	User::Leave(KErrNotSupported);
//	}
//
//	HBufC* str = HBufC::NewL(aBodyData.Length());
//	CleanupStack::PushL(str);
//
//	TPtr ptr = str->Des();
//	TInt state = CCnvCharacterSetConverter::KStateDefault;
//
//	if (conv->ConvertToUnicode(ptr, aBodyData, state) == CCnvCharacterSetConverter::EErrorIllFormedInput)
//	{
//	User::Leave(KErrArgument);
//	}
//
//	fs.Close();
//	CleanupStack::PopAndDestroy(2);
	
	
	//HBufC16* buf16 = HBufC16::NewLC(aBodyData.Length()); 
	
	//TPtrC16 ptr16(buf16-> Des()); 

//				// Convert to 16-bit descriptor 
//	HBufC16* buf16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aBodyData);
//	CleanupStack::PushL(buf16);
//	TPtr ptr = buf16->Des();
	
	
	
	//console->Write(ptr);
	
	
	
	//如果返回的是城市列表
		if (iGetDataType == ECity)
			{
//				CJsonBuilder* jsonBuilder = CJsonBuilder::NewL();
////				CleanupStack::PushL(jsonBuilder);
//				// this will create json string representation in memory
//				jsonBuilder->BuildFromJsonStringL(ptr);
//				
//				CJsonArray* values;
////				CleanupStack::PushL(values);
//				jsonBuilder->GetDocumentArray(values);
//				
//				RArray<TCity> rArray;
//				
//				if (values)
//					{
//					for (TInt i=0;i<values->Count();i++)
//						{
//						
//						CJsonObject* project;
//						values->GetObject(i,project);
//						
//						if(project)
//							{
//							
//								TCity city;
//								project->GetStringL(_L("n"), city.iName);
//								project->GetStringL(_L("i"), city.iId);
//								
//								rArray.Append(city);
//							}
//						
//						// we need manually release created object
//						delete project;
//						
//						}
//					}
//				
//				//delete values;
//				// releases only jsonBuilder object, not objects which was created by him
//				delete jsonBuilder;
				
				CJSONValue* v0 = CJSONValue::NewL();
				CJSONValue& vv = *v0;
				TInt ret = vv.Parse(aBodyData);
				ASSERT(ret == aBodyData.Length());
				CJSONArray& v = vv.Get<CJSONArray>();
				
				RArray<TCity> rArray;
				
				for (TInt i=0;i<v.Size();i++)
					{
						CJSONObject& o = v.Get<CJSONObject>(i);
						
						TCity city;
						//TBuf8<20> test = o.Get<TDesC8>(_L8("n"));
						HBufC8* hBuf8Name = DecodeJSONString1(o.Get<TDesC8>(_L8("n")));
						HBufC16* buf16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*hBuf8Name);
						//CleanupStack::PushL(buf16);
						TPtr ptr = buf16->Des();
						city.iName = ptr;
						
						city.iId = o.Get<TInt64>(_L8("i"));
						rArray.Append(city);
						//CleanupStack::PopAndDestroy(buf16);
						
						delete (hBuf8Name);
						delete (buf16);
						
					}
				delete v0;
			
				iObserver->CitysReceived(rArray);

			}
		else if (iGetDataType == EExhibitionHall)
			{
			
//				CJsonBuilder* jsonBuilder = CJsonBuilder::NewL();
//				
//				// this will create json string representation in memory
//				jsonBuilder->BuildFromJsonStringL(ptr);
//				
//				CJsonObject* rootObject;
//				jsonBuilder->GetDocumentObject(rootObject);
//				RArray<TExhibitionHall> rArray;
//				
//				if(rootObject)
//					{
//					CJsonArray* values;
//					rootObject->GetArrayL(_L("v"), values);
//					
//					if (values)
//						{
//						for (TInt i=0;i<values->Count();i++)
//							{
//							
//							CJsonObject* project;
//							values->GetObject(i,project);
//							
//							if(project)
//								{
//								
//									TExhibitionHall exhibitionHall;
//									project->GetStringL(_L("VenueID"), exhibitionHall.iId);
//									project->GetStringL(_L("Name"), exhibitionHall.iName);
//									project->GetStringL(_L("AddRess"), exhibitionHall.iAddress);
//									
//									rArray.Append(exhibitionHall);
//								}
//							
//							// we need manually release created object
//							delete project;
//							
//							}
//						}
//
//					}
//				
//
//	//			delete values;
//
//				// we need manually release created object
////				delete rootObject;
//				
//				// releases only jsonBuilder object, not objects which was created by him
//				delete jsonBuilder;		
//				
//				iObserver->ExhibitionHallsReceived(rArray);
//			
			
			
				CJSONObject* o0 = CJSONObject::NewL();
				CJSONObject& o=*o0;
				TInt ret = o.Parse(*hBufC8Encode);
				CJSONArray& v = o.Get<CJSONArray>(_L8("v"));
				
				RArray<TExhibitionHall> rArray;
				
				for (TInt i=0;i<v.Size();i++)
					{
						CJSONObject& o1 = v.Get<CJSONObject>(i);
						
						TExhibitionHall exhibitionHall;
						
						HBufC8* hBuf8Name = DecodeJSONString1(o1.Get<TDesC8>(_L8("Name")));
						HBufC16* hbuf16Name = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*hBuf8Name);
						exhibitionHall.iName = hbuf16Name->Des();
						
						HBufC8* hBuf8Address = DecodeJSONString1(o1.Get<TDesC8>(_L8("AddRess")));
						HBufC16* hBuf16Address = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*hBuf8Address);
						exhibitionHall.iAddress = hBuf16Address->Des();
						
						exhibitionHall.iId = o1.Get<TInt64>(_L8("VenueID"));
						rArray.Append(exhibitionHall);
						
						delete (hBuf8Name);
						delete (hbuf16Name);
						delete (hBuf8Address);
						delete (hBuf16Address);
						
												
					}
				delete o0;
			
				iObserver->ExhibitionHallsReceived(rArray);
			
			}
		else if (iGetDataType == EExhibitionHallItem)
			{
//				CJsonBuilder* jsonBuilder = CJsonBuilder::NewL();
//				
//				// this will create json string representation in memory
//				jsonBuilder->BuildFromJsonStringL(ptr);
//				
//				CJsonObject* rootObject;
//				jsonBuilder->GetDocumentObject(rootObject);
//				RArray<TExhibitionHallItem> rArray;
//				
//				if(rootObject)
//					{
//					
//					CJsonArray* values;
//					rootObject->GetArrayL(_L("l"), values);
//					
//					if (values)
//						{
//						for (TInt i=0;i<values->Count();i++)
//							{
//							
//							CJsonObject* project;
//							values->GetObject(i,project);
//							
//							if(project)
//								{
//								
//									TExhibitionHallItem exhibitionHallItem;
//									project->GetStringL(_L("i"), exhibitionHallItem.iId);
//									project->GetStringL(_L("n"), exhibitionHallItem.iProjectName);
//									project->GetStringL(_L("IsOnlyXuanZuo"), exhibitionHallItem.iState);
//									project->GetStringL(_L("t"), exhibitionHallItem.iPeriod);
//									project->GetStringL(_L("p"), exhibitionHallItem.iPrice);
//									
//									rArray.Append(exhibitionHallItem);
//								}
//							
//							// we need manually release created object
//							delete project;
//							
//							}
//						}
//		
//					}
//				
//		
//		//			delete values;
//		
//				// we need manually release created object
//				delete rootObject;
//				
//				// releases only jsonBuilder object, not objects which was created by him
//				delete jsonBuilder;		
//				
//				iObserver->ExhibitionHallItemsReceived(rArray);
			
			
			
			
			CJSONObject* o0 = CJSONObject::NewL();
			CJSONObject& o=*o0;
			TInt ret = o.Parse(*hBufC8Encode);
			CJSONArray& v = o.Get<CJSONArray>(_L8("l"));
			
			RArray<TExhibitionHallItem> rArray;
			
			for (TInt i=0;i<v.Size();i++)
				{
					CJSONObject& o1 = v.Get<CJSONObject>(i);
					
					TExhibitionHallItem exhibitionHallItem;
					
					HBufC8* hBuf8Name = DecodeJSONString1(o1.Get<TDesC8>(_L8("n")));
					HBufC16* hbuf16Name = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*hBuf8Name);
					exhibitionHallItem.iProjectName = hbuf16Name->Des();
					
//					HBufC8* hBuf8State = DecodeJSONString1(o1.Get<TInt64>(_L8("s")));
//					HBufC16* hBuf16State = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*hBuf8State);
					exhibitionHallItem.iState = o1.Get<TInt64>(_L8("s"));
					
					exhibitionHallItem.iId = o1.Get<TInt64>(_L8("i"));
					
					
					HBufC8* hBuf8Period = DecodeJSONString1(o1.Get<TDesC8>(_L8("t")));
					HBufC16* hbuf16Period = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*hBuf8Period);
					exhibitionHallItem.iPeriod = hbuf16Period->Des();					
					
					HBufC8* hBuf8iPrice = DecodeJSONString1(o1.Get<TDesC8>(_L8("p")));
					HBufC16* hbuf16iPrice = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*hBuf8iPrice);
					exhibitionHallItem.iPrice = hbuf16iPrice->Des();	
					
					rArray.Append(exhibitionHallItem);
					
					delete (hBuf8Name);
					delete (hbuf16Name);
//					delete (hBuf8State);
//					delete (hBuf16State);
					delete (hBuf8Period);
					delete (hbuf16Period);
					delete (hBuf8iPrice);
					delete (hbuf16iPrice);
					
											
				}
			delete o0;
		
			iObserver->ExhibitionHallItemsReceived(rArray);
			
//			
			}
		

	
		delete (hBufC8Encode);
								
//		CleanupStack::PopAndDestroy(buf16aBodyData);
	}



// ---------------------------------------------------------
// Set observer.
// ---------------------------------------------------------
//
void CDaMaiModel::SetObserver(MReceiveObserver* aObserver)
	{
	iObserver = aObserver;
	}

//获取城市数据 
void CDaMaiModel::GetCitys()
	{
	// Issue HTTP get to engine; first cancel possible existing transaction
	iClient->CancelTransaction();
	// Start transaction
	iClient->IssueHTTPGetL(KCityURL);
	//设置当前数据类型
	iGetDataType = ECity;
	}

//展馆
void CDaMaiModel::GetExhibitionHalls(TInt64 id)
	{
		
		TBuf8<256> tBufURL;
		tBufURL.Append(KExhibitionHallURL);
		tBufURL.AppendNum(id);
		
		// Issue HTTP get to engine; first cancel possible existing transaction
		iClient->CancelTransaction();
		// Start transaction
		iClient->IssueHTTPGetL(tBufURL);
		//设置当前数据类型
		iGetDataType = EExhibitionHall;
	}


//展馆详细
void CDaMaiModel::GetExhibitionHallDetails(TInt64 id)
	{
		TBuf8<256> tBufURL;
		tBufURL.Append(KExhibitionHallItemURL);
		tBufURL.AppendNum(id);
		
		// Issue HTTP get to engine; first cancel possible existing transaction
		iClient->CancelTransaction();
		// Start transaction
		iClient->IssueHTTPGetL(tBufURL);
		//设置当前数据类型
		iGetDataType = EExhibitionHallItem;
	}





